<template>
  <div class="authorization-field">
    <div class="content">
      <div class="top">
        字段授权：
        <je-select
          v-model:value="fieldValue"
          :style="{ marginRight: '100px' }"
          :options="SQLOptions"
          :allow-clear="false"
        ></je-select>
        授权范围：
        <je-select
          v-model:value="authorizationValue"
          :disabled="disabled"
          :style="{ marginRight: '100px' }"
          :options="authorizationOptions"
          :allow-clear="false"
          @change="changeEvent"
        ></je-select>
        控制范围：
        <je-select
          v-model:value="ctrValue"
          :disabled="disabled"
          :style="{ marginRight: '100px' }"
          :options="ctrOptions"
          :allow-clear="false"
        ></je-select>
        选择控制：
        <je-select
          v-model:value="changeCtrValue"
          :disabled="disabled"
          :options="changeCtrOptions"
          :allow-clear="false"
        ></je-select>
      </div>
      <div class="table">
        <je-grid
          ref="xTable"
          align="left"
          type
          keep-source
          class="table-xTable"
          :checkbox-config="{
            checkField: 'checked',
            checkMethod: ({ row }) => {
              return !disabled && row.bean.ROLE_TYPE_CODE !== 'folder';
            },
            checkStrictly: true,
            cascadeChild: false,
            cascadeParent: false,
          }"
          :tree-config="{
            trigger: 'cell-dblclick',
            rowField: 'id',
            parentField: 'parent',
            expandAll: true,
          }"
          :row-config="{
            keyField: 'id',
            labelField: 'text',
          }"
          :row-style="rowStyle"
          :data="tableData"
          :auto-load="true"
          size="mini"
          :loading="loading"
          show-overflow="ellipsis"
          height="100%"
          resizable
          auto-resize
          header-row-class-name="headerHeight"
          :filter-config="{ showIcon: false }"
          @checkbox-change="handlerSelect"
        >
          <!-- <je-column type="seq" width="50" title="No."></je-column> -->
          <je-column type="checkbox" :title="title" width="250" tree-node :disabled="disabled">
            <template #nodeIcon="{ row }">
              <i
                v-if="row.bean.ROLE_TYPE_CODE === 'folder' && row.children.length === 0"
                class="is--folder fas fa-folder"
              ></i>
            </template>
            <template #header>
              <je-switch v-model:checked="column.checked" mode="checkbox" :disabled="disabled" />
            </template>
          </je-column>
          <template v-if="!disabled">
            <je-column
              v-for="item in funcList"
              :key="item.JE_CORE_RESOURCEFIELD_ID"
              :field="item.JE_CORE_RESOURCEFIELD_ID"
              :title="item.RESOURCEFIELD_NAME"
              width="160"
              align="center"
              type="switch"
            >
              <template #header="{ column }">
                <je-switch v-model:value="myColumn[column.field]" mode="checkbox" />&nbsp;
                <span>{{ column.title }}</span>
              </template>
            </je-column>
          </template>
          <template v-else>
            <je-column
              v-for="item in funcList"
              :key="item.JE_CORE_RESOURCEFIELD_ID"
              :field="item.JE_CORE_RESOURCEFIELD_ID"
              :title="item.RESOURCEFIELD_NAME"
              width="160"
              align="center"
            >
              <template #header="{ column }">
                <je-switch
                  v-model:value="myColumn[column.field]"
                  mode="checkbox"
                  :disabled="disabled"
                />&nbsp;
                <span>{{ column.title }}</span>
              </template>
              <template #default="{ row, column }">
                <je-switch v-model:value="row[column.field]" mode="checkbox" :disabled="true" />
              </template>
            </je-column>
          </template>
        </je-grid>
      </div>
    </div>
    <div class="footer">
      <je-button type="primary" :disabled="btnDisabled" class="btn" @click="save"
        >保存刷新</je-button
      >
      <je-button class="btn" :disabled="disabled || btnDisabled" @click="reset">恢复数据</je-button>
      <je-button class="btn" @click="closeEvent">关闭</je-button>
    </div>
  </div>
</template>

<script>
  import { defineComponent, onMounted, ref, watch } from 'vue';

  import { Grid, Button, Select, Switch, Modal } from '@jecloud/ui';

  import {
    getPremDataApi,
    loadOrgApi,
    loadDepartmentTreeApi,
    loadRoleTreeApi,
    doSaveApi,
  } from '@/api/authorization';

  import { useDialog } from '@/hooks/use-dialog';

  import {
    JE_DATAAUTHORITY_AFAUTHORIZATIONOPTIONS,
    JE_DATAAUTHORITY_AFCHANGECTROPTIONS,
    JE_DATAAUTHORITY_AFCTROPTIONS,
    JE_DATAAUTHORITY_AFSQLOPTIONS,
  } from '@/helper/constant';

  export default defineComponent({
    name: 'AuthorizationField',
    components: {
      JeButton: Button,
      JeSelect: Select,
      JeGrid: Grid,
      JeColumn: Grid.Column,
      JeSwitch: Switch,
    },
    props: {
      currentFuncId: {
        type: String,
        default: '',
      },
      currentFuncCode: {
        type: String,
        default: '',
      },
      parentModal: String,
    },
    emits: ['isChange'],
    setup(props, { emit }) {
      const resRusult = ref([]); // 返回结果
      const xTable = ref('xTable');
      const loading = ref(false);

      const fieldValue = ref('0'); // SQL值
      // SQL选项
      const SQLOptions = JE_DATAAUTHORITY_AFSQLOPTIONS;
      const authorizationValue = ref('0'); // 授权范围值
      // 授权范围选项
      const authorizationOptions = JE_DATAAUTHORITY_AFAUTHORIZATIONOPTIONS;
      const ctrValue = ref('0'); // 控制范围值
      // 控制范围选项
      const ctrOptions = JE_DATAAUTHORITY_AFCTROPTIONS;
      const changeCtrValue = ref('0'); // 选择控制值
      // 选择控制选项
      const changeCtrOptions = JE_DATAAUTHORITY_AFCHANGECTROPTIONS;

      const disabled = ref(true); // 展示有功能授权的所有角色值
      const btnDisabled = ref(false); // 按钮禁用

      // 表格数据
      const tableData = ref([]);
      // 页面所有数据
      const allData = ref({});
      // 传参
      const payloadData = ref({
        roleAuthFieldVo: {},
        deptAuthFieldVo: {},
        orgAuthFieldVo: {},
      });

      // 页面
      let metaOpen = '0'; //对比项
      let metaCValue = '0'; //对比项
      let meteChangeCtraOpen = '0'; //对比项
      const title = ref('角色授权');

      // 选择授权范围
      const changeEvent = (e) => {
        restAllData();
        loading.value = true;
        if (e === '0') {
          // 角色
          title.value = '角色授权';
        } else if (e === '1') {
          // 部门
          title.value = '部门授权';
        } else if (e === '2') {
          // 机构
          title.value = '机构授权';
        }
        changeAuthorizationEvent();
      };

      const funcId = ref('');
      const funcCode = ref('');

      // 保存
      const save = () => {
        if (isChange()) return Modal.notice('无数据操作!', 'info');
        // 得到所有数据
        getAllData();
        btnDisabled.value = true;
        // 保存接口
        doSaveApi({
          tableCode: 'JE_CORE_FUNCPERM',
          FUNCPERM_FUNCINFO_CODE: funcCode.value,
          FUNCPERM_FUNCINFO_ID: funcId.value,
          FUNCPERM_TYPE: 'fieldAuth',
          FUNCPERM_ON_OFF: fieldValue.value,
          FUNCPERM_CONFIG: JSON.stringify(payloadData.value),
        })
          .then((res) => {
            Modal.notice(res.message, 'success');
            // 重新保存对比数据
            metaOpen = JSON.parse(JSON.stringify(fieldValue.value));
            metaCValue = JSON.parse(JSON.stringify(ctrValue.value));
            meteChangeCtraOpen = JSON.parse(JSON.stringify(changeCtrValue.value));
            //刷新列表数据
            xTable.value.loadData(tableData.value);
            btnDisabled.value = false;
          })
          .catch((err) => {
            Modal.alert(err.message, 'error');
            btnDisabled.value = false;
          });
      };

      const funcList = ref([]); // 功能字段数组
      const funcCodeList = ref([]); // 功能字段code数组
      let myColumn = ref({}); // 表头的参数
      let myColumnCopy = {}; // 表头的参数对比项
      // 保存前处理数据
      const getAllData = () => {
        // 置空
        allData.value = {};
        datas = [];
        // 得到所有修改项
        const arr = xTable.value.getUpdateRecords();
        // 得到页面所有数据
        getPageAllData(arr);
        allData.value['controlScope'] = ctrValue.value;
        allData.value['selectControl'] = changeCtrValue.value;
        if (title.value === '角色授权') {
          payloadData.value.roleAuthFieldVo = allData.value;
        } else if (title.value === '部门授权') {
          payloadData.value.deptAuthFieldVo = allData.value;
        } else {
          payloadData.value.orgAuthFieldVo = allData.value;
        }
      };
      // 保存数据是否改变
      const isChange = () => {
        // 改变项的数组
        const arr = xTable.value.getUpdateRecords();
        let res = true;
        const res1 = metaOpen === fieldValue.value;
        const res2 = metaCValue === ctrValue.value;
        const res3 = meteChangeCtraOpen === changeCtrValue.value;
        if (arr.length > 0) res = false;
        return res && res1 && res2 && res3;
      };

      // 递归得到页面数据
      let datas = [];
      const getPageAllData = (target) => {
        target.forEach((item) => {
          if (item.bean.ROLE_TYPE_CODE !== 'folder') {
            const obj = {};
            obj['id'] = item.id;
            obj['text'] = item.text;
            const allFields = [];
            Object.keys(myColumnCopy).map((key) => {
              const obj = {};
              obj['code'] = key;
              obj['value'] = item[key] || '0';
              allFields.push(obj);
            });
            obj['allFields'] = allFields;
            datas.push(obj);
            allData.value['datas'] = datas;
          }
          if (item.children.length > 0) {
            getPageAllData(item.children);
          }
        });
      };

      // 回显
      onMounted(() => {
        funcId.value = props.currentFuncId;
        funcCode.value = props.currentFuncCode;
        loading.value = true;
        getPageData('roleAuthFieldVo');
      });

      // 获得表格数据
      const getPageData = (target, flag) => {
        if (!funcId.value) return false;
        getPremDataApi({
          tableCode: 'JE_CORE_FUNCPERM',
          FUNCPERM_FUNCINFO_ID: funcId.value,
          FUNCPERM_TYPE: 'fieldAuth',
        }).then((res) => {
          // 得到树
          if (!flag) {
            resRusult.value = res[0]?.values?.roleTree.children;
          }
          // 得到表头
          funcList.value = res[0]?.values?.columnList;
          // 转化成接受数据的fields:[{code:字段code,vaule:1},{code:字段code,vaule:1}]格式
          funcList.value.forEach((item) => {
            const obj = {};
            obj['code'] = item.JE_CORE_RESOURCEFIELD_ID;
            obj['vaule'] = '0';
            myColumn.value[item.JE_CORE_RESOURCEFIELD_ID] = '0';
            funcCodeList.value.push(obj);
          });
          myColumnCopy = JSON.parse(JSON.stringify(myColumn.value));
          // 得到回显值
          let data = [];
          if (res[0]?.values?.FUNCPERM_CONFIG) {
            fieldValue.value = res[0]?.values?.FUNCPERM_ON_OFF || '0';
            data = JSON.parse(res[0]?.values?.FUNCPERM_CONFIG)[target];
            ctrValue.value = data.controlScope || '0';
            changeCtrValue.value = data.selectControl || '0';
            metaOpen = JSON.parse(JSON.stringify(fieldValue.value));
            metaCValue = JSON.parse(JSON.stringify(ctrValue.value));
            meteChangeCtraOpen = JSON.parse(JSON.stringify(changeCtrValue.value));
          }
          // 赋值
          Recursive(resRusult.value);
          if (data?.datas?.length > 0) {
            // 有返回值;
            data.datas?.forEach((item) => {
              const filedValue = {};
              funcCodeList.value = item.allFields;
              // 将[{code:字段code,vaule:1}]格式转化成表格所需要的{code:value}格式
              funcCodeList.value.map((item) => {
                if (item.value === '1') {
                  filedValue[item.code] = item.value;
                }
              });
              toSetData(resRusult.value, filedValue, item.id);
              tableData.value = resRusult.value;
              setTimeout(() => {
                tableData.value.forEach((item) => {
                  const row = xTable.value.getRowById(item.id);
                  xTable.value.setTreeExpand(row, true);
                });
              }, 0);
              loading.value = false;
            });
          } else {
            // 没有返回值，递归给树的每一项加filedValue字段，并赋值
            tableData.value = resRusult.value;
            setTimeout(() => {
              tableData.value.forEach((item) => {
                const row = xTable.value.getRowById(item.id);
                xTable.value.setTreeExpand(row, true);
              });
            }, 0);
            loading.value = false;
          }
        });
      };

      // 递归赋空值
      const Recursive = (data) => {
        data.forEach((item) => {
          const filedValue = {};
          funcCodeList.value.map((td) => {
            filedValue[td.code] = '0';
          });
          Object.keys(filedValue).forEach((td) => {
            item[td] = filedValue[td];
          });
          if (item.children.length > 0) {
            Recursive(item.children);
          }
        });
      };
      // 递归赋值
      const toSetData = (data, filedValue, id) => {
        data.forEach((item) => {
          if (item.id === id) {
            Object.keys(filedValue).forEach((td) => {
              item[td] = filedValue[td];
            });
          }
          if (item.children.length > 0) {
            toSetData(item.children, filedValue, id);
          }
        });
      };

      // 点击tree组件
      const handlerSelect = ({ row }) => {
        changeLandscapeValue(row);
      };
      // 横向全选
      const changeLandscapeValue = (row) => {
        Object.keys(myColumnCopy).forEach((key) => {
          row[key] = row.checked ? '1' : '0';
        });
        if (row.children.length > 0) {
          row.children.forEach((item) => {
            changeLandscapeValue(item);
          });
        }
      };

      // 恢复数据
      const reset = () => {
        Modal.confirm('您确定要恢复数据吗？', () => {
          toReset();
        });
      };

      // 回退数据
      const toReset = () => {
        btnDisabled.value = true;
        fieldValue.value = JSON.parse(JSON.stringify(metaOpen));
        ctrValue.value = JSON.parse(JSON.stringify(metaCValue));
        changeCtrValue.value = JSON.parse(JSON.stringify(meteChangeCtraOpen));
        changeAuthorizationEvent(true);
      };

      // 授权范围变化
      const changeAuthorizationEvent = (bol = false) => {
        if (title.value === '角色授权') {
          loadRoleTreeApi().then((res) => {
            resRusult.value = res.children;
            getPageData('roleAuthFieldVo');
            bol && (btnDisabled.value = false);
          });
        } else if (title.value === '部门授权') {
          loadDepartmentTreeApi().then((res) => {
            resRusult.value = res.children;
            getPageData('deptAuthFieldVo', 'flag');
            bol && (btnDisabled.value = false);
          });
        } else {
          loadOrgApi({ excludeDepartment: '1' }).then((res) => {
            resRusult.value = res.children;
            getPageData('orgAuthFieldVo', 'flag');
            bol && (btnDisabled.value = false);
          });
        }
      };

      watch(
        () => fieldValue.value,
        (nv) => {
          disabled.value = nv === '0';
        },
        { immediate: true },
      );

      // 清空数据
      const restAllData = () => {
        allData.value = {};
      };

      // 关闭
      const closeEvent = () => {
        props.parentModal.close();
      };

      // 监听表头参数，全选
      watch(
        () => myColumn.value,
        (nv) => {
          const key = Object.keys(nv).filter((key) => {
            return nv[key] !== myColumnCopy[key];
          });
          if (key.length === 0) return false;
          changeAllValue(tableData.value, key[0], nv[key[0]]);
          myColumnCopy = JSON.parse(JSON.stringify(myColumn.value));
        },
        { deep: true },
      );

      // 递归全选
      const changeAllValue = (arr, _key, _value) => {
        arr.forEach((item) => {
          if (item.bean.ROLE_TYPE_CODE !== 'folder') {
            item[_key] = _value;
          }
          if (item.children.length > 0) {
            changeAllValue(item.children, _key, _value);
          }
        });
      };

      // 行样式
      const rowStyle = ({ row }) => {
        if (row.bean.ROLE_TYPE_CODE === 'folder') {
          return {
            background: '#F5F5F5',
            pointerEvents: 'none',
          };
        }
      };

      // 切换tab
      const changeTabCb = () => {
        const flag = isChange();
        if (flag) return emit('isChange', flag);
        // 弹框
        useDialog({ toReset, save, isDicOrRole: false });
      };

      return {
        fieldValue,
        SQLOptions,
        ctrValue,
        ctrOptions,
        authorizationValue,
        authorizationOptions,
        changeCtrValue,
        changeCtrOptions,
        disabled,
        tableData,
        loading,
        xTable,
        funcList,
        btnDisabled,
        title,
        save,
        changeEvent,
        myColumn,
        handlerSelect,
        rowStyle,
        reset,
        closeEvent,
        changeTabCb,
      };
    },
  });
</script>

<style lang="less" scoped>
  .authorization-field {
    display: flex;
    flex-direction: column;
    height: 100%;
    padding: 0 20px;
    border: 1px solid #d7d7d7;
    background: #edf0f4;
    justify-content: space-between;
    align-items: start;
    :deep(.vxe-table--header .vxe-cell--checkbox-icon) {
      display: none;
    }
    :deep(.headerHeight .vxe-cell--title .vxe-cell--checkbox-label) {
      text-align: center !important;
      margin-left: 90px;
    }
    .footer {
      height: 0px;
      min-height: 70px;
      .btn {
        margin-right: 15px;
        margin-top: 20px;
      }
    }
    .content {
      padding-top: 20px;
      flex: '1';
      height: 100%;
      width: 100%;
      display: flex;
      flex-direction: column;
      overflow-y: auto;
      overflow-x: auto;
      &::-webkit-scrollbar {
        display: none;
      }
      .top {
        padding-left: 16px;
        width: 100%;
        height: 50px;
        background: #ffffff;
        line-height: 50px;
      }
      .table {
        flex: 1;
        // min-width: 1000px;
        margin-top: 16px;
        width: 100%;
        height: 100%;
        background: #ffffff;
        // overflow-x: auto;
        // &::-webkit-scrollbar {
        //   display: none;
        // }
      }
    }
  }
</style>
